﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Principal;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace Protocal.App.Common
{
    public class ValidationHelper
    {
        private static Dictionary<string, Func<object,CheckResult>> handleMapping = new Dictionary<string, Func<object, CheckResult>>();

        // 静态构造函数初始化所有验证规则
        static ValidationHelper()
        {
            // 用户名验证规则
            AddHandleMapping("Username", value =>
            {
                var str = value as string;
                if (string.IsNullOrWhiteSpace(str))
                {
                    return new CheckResult { State = false, Msg = "用户名不能为空" };
                }
                if (str.Length < 4 || str.Length > 20)
                {
                    return new CheckResult { State = false, Msg = "用户名长度需在4-20个字符之间" };
                }
                if (!Regex.IsMatch(str, @"^[a-zA-Z0-9_]+$"))
                {
                    return new CheckResult { State = false, Msg = "用户名只能包含字母、数字和下划线" };
                }
                return new CheckResult { State = true };
            });

            // 账号验证规则
            AddHandleMapping("Account", value =>
            {
                var str = value as string;
                if (string.IsNullOrWhiteSpace(str))
                {
                    return new CheckResult { State = false, Msg = "账号不能为空" };
                }
                if (str.Length < 6 || str.Length > 30)
                {
                    return new CheckResult { State = false, Msg = "账号长度需在6-30个字符之间" };
                }
                return new CheckResult { State = true };
            });

            // 手机号验证规则
            AddHandleMapping("Phone", value =>
            {
                var str = value as string;
                if (string.IsNullOrWhiteSpace(str))
                {
                    return new CheckResult { State = false, Msg = "手机号不能为空" };
                }
                if (!Regex.IsMatch(str, @"^1[3-9]\d{9}$"))
                {
                    return new CheckResult { State = false, Msg = "请输入有效的手机号码" };
                }
                return new CheckResult { State = true };
            });

            // 邮箱验证规则
            AddHandleMapping("Email", value =>
            {
                var str = value as string;
                if (string.IsNullOrWhiteSpace(str))
                {
                    return new CheckResult { State = false, Msg = "邮箱不能为空" };
                }
                if (!Regex.IsMatch(str, @"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$"))
                {
                    return new CheckResult { State = false, Msg = "请输入有效的邮箱地址" };
                }
                return new CheckResult { State = true };
            });

            // 密码验证规则
            AddHandleMapping("Password", value =>
            {
                var str = value as string;
                if (string.IsNullOrWhiteSpace(str))
                {
                    return new CheckResult { State = false, Msg = "密码不能为空" };
                }
                if (str.Length < 8 || str.Length > 20)
                {
                    return new CheckResult { State = false, Msg = "密码长度需在8-20个字符之间" };
                }
                if (!Regex.IsMatch(str, @"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).+$"))
                {
                    return new CheckResult { State = false, Msg = "密码必须包含大小写字母和数字" };
                }
                return new CheckResult { State = true };
            });
        }

        public static CheckResult Validate(string name, object value)
        {
            CheckResult result = new CheckResult();
            if (handleMapping.TryGetValue(name, out Func<object, CheckResult> action))
            {
                result = action.Invoke(value);
            }
            else
            {
                result.State = false;
                result.Msg = "未定义对应的校验方法";
            }

            return result;
        }

        public static void AddHandleMapping(string name, Func<object, CheckResult> handle)
        {
            if (!handleMapping.ContainsKey(name))
            {
                handleMapping.Add(name, handle);
            }
            else
            {
                handleMapping[name] = handle;
            }
        }
    }

    public class CheckResult
    {
        public bool State { get; set; }
        public string Msg { get; set; }
    }
}
